package modelo.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import modelo.*;
import util.*;

/*
 * Maneja entidades:
 *   - Marcas
 *   - Modelos
 *   - Equipos
 */

public class DAOEquipos {
	protected HashMap<Integer, Marca> marcas = new HashMap<Integer, Marca>();
	protected HashMap<Pair<Integer, String>, Modelo> modelos = new HashMap<Pair<Integer, String>, Modelo>();
	protected HashMap<Integer, Equipo> equipos = new HashMap<Integer, Equipo>();
	
	public void cargarMarcas() {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM marca\n"
			);
		
		try {
			while (rs.next())
				marcas.put(rs.getInt("cod_marca"), new Marca(rs.getInt("cod_marca"), rs.getString("nombre"), Status.valueOf(rs.getInt("status"))));
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public ArrayList<Marca> consultarMarcas() {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM marca\n"
			);
		
		return adjuntarMarca(rs);
	}
	
	public Marca consultarMarcaPorCodigo(int cod) {
		return marcas.get(cod);
	}
	
	/*
	public Marca agregarMarca(String nombre, Status status) {
		try {
			ResultSet rs = Servidor.consultar(
				"INSERT INTO sucursal\n" +
				"    (nombre, status)\n" +
				"VALUES\n" +
				"	 ('" + nombre + "', " + status.toInt() + ")\n" +
				"RETURNING cod_marca"
				);
				
			if (!rs.next()) return null;
				
			Marca e = new Marca(rs.getInt("cod_marca"), nombre, status);
			marcas.put(e.getCodigo(), e);
			
			return e;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public Marca modificarMarca(Marca marca) {
		boolean b = Servidor.ejecutar(
			"UPDATE marca\n" +
			"SET nombre = '" + marca.getNombre() + "',\n" +
			"    status = " + marca.getStatus().toInt() + "\n" +
			"WHERE cod_marca = " + marca.getCodigo() + "\n"
			);
		
		if (!b) return null;
		
		return marca;
	}
	*/
	
	private ArrayList<Marca> adjuntarMarca(ResultSet rs) {
		ArrayList<Marca> lst = new ArrayList<Marca>();
		
		try {
			while (rs.next())
				lst.add(marcas.get(rs.getInt("cod_marca")));
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return lst;
	}
	
	public void cargarModelos() {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM modelo\n"
			);
		
		try {
			while (rs.next())
				modelos.put(new Pair<Integer, String>(rs.getInt("cod_marca"), rs.getString("cod_modelo")), new Modelo(rs.getString("cod_modelo"), rs.getString("nombre"), consultarMarcaPorCodigo(rs.getInt("cod_marca")), Status.valueOf(rs.getInt("status"))));
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public ArrayList<Modelo> consultarModelosPorMarca(int codigoMarca) {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM modelo\n" +
			"WHERE cod_marca = " + codigoMarca + "\n"
			);
		
		return adjuntarModelo(rs);
	}
	
	public Modelo consultarModeloPorCodigo(int codigoMarca, String codigoModelo) {
		return modelos.get(new Pair<Integer, String>(codigoMarca, codigoModelo));
	}
	
	/*
	public Modelo agregarModelo(String codigo, String nombre, Marca marca, Status status) {
		try {
			ResultSet rs = Servidor.consultar(
				"INSERT INTO marca\n" +
				"    (cod_modelo, nombre, cod_marca, status)\n" +
				"VALUES\n" +
				"    ('" + codigo + "', '" + nombre + "', " + marca.getCodigo() + ", " + status + ")\n"
				);
				
			if (!rs.next()) return null;

			
			Modelo m = new Modelo(codigo, nombre, marca, status);
			modelos.put(new Pair<Integer, String>(rs.getInt("cod_marca"), rs.getString("cod_modelo")), m);
			
			return m;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public Modelo modificarModelo(Modelo modelo) {
		boolean b = Servidor.ejecutar(
			"UPDATE modelo\n" +
			"SET nombre = '" + modelo.getNombre() + "',\n" +
			"    status = " + modelo.getStatus().toInt() + "\n" +
			"WHERE cod_modelo = '" + modelo.getCodigo() + "' AND\n" +
			"      cod_marca = " + modelo.getMarca().getCodigo() + "\n"
			);
		
		if (!b) return null;
		
		return modelo;
	}
	*/
	
	private ArrayList<Modelo> adjuntarModelo(ResultSet rs) {
		ArrayList<Modelo> lst = new ArrayList<Modelo>();
		
		try {
			while (rs.next())
				lst.add(modelos.get(new Pair<Integer, String>(rs.getInt("cod_marca"), rs.getString("cod_modelo"))));
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return lst;
	}
	
	public void cargarEquipos() {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM equipo\n"
			);
		
		try {
			while (rs.next()) {
				Equipo e = new Equipo(rs.getInt("cod_equipo"), rs.getString("descripcion"), rs.getString("comentarios"), consultarModeloPorCodigo(rs.getInt("cod_marca"), rs.getString("cod_modelo")), Servidor.clientes().consultarSucursalPorCodigo(rs.getInt("cod_sucursal")), Status.valueOf(rs.getInt("status")));
				equipos.put(e.clave(), e);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public ArrayList<Equipo> consultarEquiposPorSucursal(int codigoSucursal) {
		ResultSet rs = Servidor.consultar(
			"SELECT cod_equipo\n" +
			"FROM equipo\n" +
			"WHERE cod_sucursal = " + codigoSucursal + "\n"
			);
		
		return adjuntarEquipo(rs);
	}
	
	public Equipo consultarEquipoPorCodigo(int codigoEquipo) {
		return equipos.get(codigoEquipo);
	}
	
	public Equipo agregarEquipo(String descripcion, String comentarios, Modelo modelo, Sucursal sucursal, Status status) {
		try {
			ResultSet rs = Servidor.consultar(
				"INSERT INTO equipo\n" +
				"    (descripcion, comentarios, cod_modelo, cod_sucursal, status)\n" +
				"VALUES\n" +
				"    ('" + descripcion + "', '" + comentarios + "', '" + modelo.getCodigo() + "', " + sucursal.getCodigo() + ", " + status.toInt() + ")\n" +
				"RETURNING cod_equipo"
				);
				
			if (!rs.next()) return null;
			
			Equipo e = new Equipo(rs.getInt("cod_equipo"), descripcion, comentarios, modelo, sucursal, status);
			equipos.put(e.clave(), e);
			
			return e;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public Equipo modificarEquipo(Equipo equipo) {
		boolean b = Servidor.ejecutar(
			"UPDATE equipo\n" +
			"SET descripcion = '" + equipo.getDescripcion() + "',\n" +
			"    comentarios = '" + equipo.getComentario() + "'\n" +
			"    cod_modelo = " + equipo.getModelo().getCodigo() + "\n" +
			"    cod_sucursal = " + equipo.getSucursal().getCodigo() + "\n" +
			"    status = " + equipo.getStatus().toInt() + "\n" +
			"WHERE cod_equipo = " + equipo.getCodigo() + "\n"
			);
		
		if (!b) return null;
		
		return equipo;
	}
	
	private ArrayList<Equipo> adjuntarEquipo(ResultSet rs) {
		ArrayList<Equipo> lst = new ArrayList<Equipo>();
		
		try {
			while (rs.next())
				lst.add(equipos.get(rs.getInt("cod_equipo")));
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return lst;
	}
}
